<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=11"/>
<meta name="generator" content="Doxygen 1.9.4"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<title>Flow: flow::async::Task_qing_thread Class Reference</title>
<link href="tabs.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="dynsections.js"></script>
<link href="search/search.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="search/searchdata.js"></script>
<script type="text/javascript" src="search/search.js"></script>
<link href="doxygen.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
<div id="titlearea">
<table cellspacing="0" cellpadding="0">
 <tbody>
 <tr id="projectrow">
  <td id="projectalign">
   <div id="projectname">Flow<span id="projectnumber">&#160;2.0.0</span>
   </div>
   <div id="projectbrief">Flow project: Full implementation reference.</div>
  </td>
 </tr>
 </tbody>
</table>
</div>
<!-- end header part -->
<!-- Generated by Doxygen 1.9.4 -->
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
var searchBox = new SearchBox("searchBox", "search",'Search','.html');
/* @license-end */
</script>
<script type="text/javascript" src="menudata.js"></script>
<script type="text/javascript" src="menu.js"></script>
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
$(function() {
  initMenu('',true,false,'search.php','Search');
  $(document).ready(function() { init_search(); });
});
/* @license-end */
</script>
<div id="main-nav"></div>
<!-- window showing the filter options -->
<div id="MSearchSelectWindow"
     onmouseover="return searchBox.OnSearchSelectShow()"
     onmouseout="return searchBox.OnSearchSelectHide()"
     onkeydown="return searchBox.OnSearchSelectKey(event)">
</div>

<!-- iframe showing the search results (closed by default) -->
<div id="MSearchResultsWindow">
<iframe src="javascript:void(0)" frameborder="0" 
        name="MSearchResults" id="MSearchResults">
</iframe>
</div>

<div id="nav-path" class="navpath">
  <ul>
<li class="navelem"><a class="el" href="namespaceflow.html">flow</a></li><li class="navelem"><a class="el" href="namespaceflow_1_1async.html">async</a></li><li class="navelem"><a class="el" href="classflow_1_1async_1_1Task__qing__thread.html">Task_qing_thread</a></li>  </ul>
</div>
</div><!-- top -->
<div class="header">
  <div class="summary">
<a href="#pub-methods">Public Member Functions</a> &#124;
<a href="#pub-static-attribs">Static Public Attributes</a> &#124;
<a href="#pri-attribs">Private Attributes</a> &#124;
<a href="classflow_1_1async_1_1Task__qing__thread-members.html">List of all members</a>  </div>
  <div class="headertitle"><div class="title">flow::async::Task_qing_thread Class Reference</div></div>
</div><!--header-->
<div class="contents">

<p>Internally used building block of various concrete <a class="el" href="classflow_1_1async_1_1Concurrent__task__loop.html" title="The core flow::async interface, providing an optionally multi-threaded thread pool onto which runnabl...">Concurrent_task_loop</a> subclasses that encapsulates a thread that spawns at construction time and a dedicated-or-shared <a class="el" href="namespaceflow_1_1util.html#ac3e89a8a271b0ddc76ac2a0ce488dea4" title="Short-hand for boost.asio event service, the central class of boost.asio.">util::Task_engine</a> (a/k/a boost.asio <code>io_context</code>) <code>run()</code>ning in that new thread.  
 <a href="classflow_1_1async_1_1Task__qing__thread.html#details">More...</a></p>

<p><code>#include &lt;<a class="el" href="task__qing__thread_8hpp_source.html">task_qing_thread.hpp</a>&gt;</code></p>
<div class="dynheader">
Inheritance diagram for flow::async::Task_qing_thread:</div>
<div class="dyncontent">
<div class="center"><iframe scrolling="no" frameborder="0" src="classflow_1_1async_1_1Task__qing__thread__inherit__graph.svg" width="310" height="119"><p><b>This browser is not able to show SVG: try Firefox, Chrome, Safari, or Opera instead.</b></p></iframe>
</div>
<center><span class="legend">[<a href="graph_legend.html">legend</a>]</span></center></div>
<div class="dynheader">
Collaboration diagram for flow::async::Task_qing_thread:</div>
<div class="dyncontent">
<div class="center"><iframe scrolling="no" frameborder="0" src="classflow_1_1async_1_1Task__qing__thread__coll__graph.svg" width="1466" height="387"><p><b>This browser is not able to show SVG: try Firefox, Chrome, Safari, or Opera instead.</b></p></iframe>
</div>
<center><span class="legend">[<a href="graph_legend.html">legend</a>]</span></center></div>
<table class="memberdecls">
<tr class="heading"><td colspan="2"><h2 class="groupheader"><a id="pub-methods" name="pub-methods"></a>
Public Member Functions</h2></td></tr>
<tr class="memitem:abb03d1b5f50a2b6148da27139a2391da"><td class="memItemLeft" align="right" valign="top">&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classflow_1_1async_1_1Task__qing__thread.html#abb03d1b5f50a2b6148da27139a2391da">Task_qing_thread</a> (<a class="el" href="classflow_1_1log_1_1Logger.html">flow::log::Logger</a> *logger_ptr, <a class="el" href="namespaceflow_1_1util.html#ae4dc52186797094b3040379ff19124c9">util::String_view</a> nickname, const <a class="el" href="namespaceflow_1_1async.html#a968806f54b14c697fd76b3339a2bdbbf">Task_engine_ptr</a> &amp;<a class="el" href="classflow_1_1async_1_1Task__qing__thread.html#aaf0191625ae2613a7351dc0515398903">task_engine</a>, <a class="el" href="classbool.html">bool</a> own_task_engine, boost::promise&lt; void &gt; *done_promise_else_block=0, <a class="el" href="namespaceflow_1_1async.html#af35fb65bdea1a3a92929ec2c4a6a6b72">Task</a> &amp;&amp;init_func_or_empty=<a class="el" href="namespaceflow_1_1async.html#af35fb65bdea1a3a92929ec2c4a6a6b72">Task</a>())</td></tr>
<tr class="memdesc:abb03d1b5f50a2b6148da27139a2391da"><td class="mdescLeft">&#160;</td><td class="mdescRight">Constructs object, immediately spawning new (worker) thread, memorizing a ref-counted reference to the provided <a class="el" href="namespaceflow_1_1util.html#ac3e89a8a271b0ddc76ac2a0ce488dea4" title="Short-hand for boost.asio event service, the central class of boost.asio.">util::Task_engine</a> which may or may not be a fresh one and meant to be shared with other <code><a class="el" href="classflow_1_1async_1_1Task__qing__thread.html" title="Internally used building block of various concrete Concurrent_task_loop subclasses that encapsulates ...">Task_qing_thread</a></code>s or exclusively by this one.  <a href="classflow_1_1async_1_1Task__qing__thread.html#abb03d1b5f50a2b6148da27139a2391da">More...</a><br /></td></tr>
<tr class="separator:abb03d1b5f50a2b6148da27139a2391da"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:abd3046b2dee9df486ba2710cb0d6b2e3"><td class="memItemLeft" align="right" valign="top">&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classflow_1_1async_1_1Task__qing__thread.html#abd3046b2dee9df486ba2710cb0d6b2e3">~Task_qing_thread</a> ()</td></tr>
<tr class="memdesc:abd3046b2dee9df486ba2710cb0d6b2e3"><td class="mdescLeft">&#160;</td><td class="mdescRight"><a class="el" href="classflow_1_1async_1_1Task__qing__thread.html#a6515b9f5240cea26b78e27ea99964ade" title="Blocks the calling thread until the constructor-started thread has finished; if the underlying Task_e...">stop()</a>, followed by forgetting the <code>Task_engine</code> returned by <a class="el" href="classflow_1_1async_1_1Task__qing__thread.html#aaf0191625ae2613a7351dc0515398903" title="Returns pointer to util::Task_engine such that post()ing to it will cause the subsequent asynchronous...">task_engine()</a>; the latter action may destroy that <code>Task_engine</code> synchronously.  <a href="classflow_1_1async_1_1Task__qing__thread.html#abd3046b2dee9df486ba2710cb0d6b2e3">More...</a><br /></td></tr>
<tr class="separator:abd3046b2dee9df486ba2710cb0d6b2e3"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:aaf0191625ae2613a7351dc0515398903"><td class="memItemLeft" align="right" valign="top"><a class="el" href="namespaceflow_1_1async.html#a968806f54b14c697fd76b3339a2bdbbf">Task_engine_ptr</a>&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classflow_1_1async_1_1Task__qing__thread.html#aaf0191625ae2613a7351dc0515398903">task_engine</a> ()</td></tr>
<tr class="memdesc:aaf0191625ae2613a7351dc0515398903"><td class="mdescLeft">&#160;</td><td class="mdescRight">Returns pointer to <a class="el" href="namespaceflow_1_1util.html#ac3e89a8a271b0ddc76ac2a0ce488dea4" title="Short-hand for boost.asio event service, the central class of boost.asio.">util::Task_engine</a> such that <code>post()</code>ing to it will cause the subsequent asynchronous execution of that task in a way explained in the <a class="el" href="classflow_1_1async_1_1Task__qing__thread.html#abb03d1b5f50a2b6148da27139a2391da" title="Constructs object, immediately spawning new (worker) thread, memorizing a ref-counted reference to th...">Task_qing_thread()</a> constructor doc header.  <a href="classflow_1_1async_1_1Task__qing__thread.html#aaf0191625ae2613a7351dc0515398903">More...</a><br /></td></tr>
<tr class="separator:aaf0191625ae2613a7351dc0515398903"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a3f9a0071880455c00a993d36c6040ae5"><td class="memItemLeft" align="right" valign="top"><a class="el" href="namespaceflow_1_1util.html#af030c3119f060a9630afca31098a78a5">util::Thread</a> *&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classflow_1_1async_1_1Task__qing__thread.html#a3f9a0071880455c00a993d36c6040ae5">raw_worker_thread</a> ()</td></tr>
<tr class="memdesc:a3f9a0071880455c00a993d36c6040ae5"><td class="mdescLeft">&#160;</td><td class="mdescRight">Returns the <a class="el" href="namespaceflow_1_1util.html#af030c3119f060a9630afca31098a78a5" title="Short-hand for standard thread class.">util::Thread</a> &ndash; a thin wrapper around the native OS thread handle &ndash; corresponding to the worker thread started in constructor.  <a href="classflow_1_1async_1_1Task__qing__thread.html#a3f9a0071880455c00a993d36c6040ae5">More...</a><br /></td></tr>
<tr class="separator:a3f9a0071880455c00a993d36c6040ae5"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a6515b9f5240cea26b78e27ea99964ade"><td class="memItemLeft" align="right" valign="top">void&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classflow_1_1async_1_1Task__qing__thread.html#a6515b9f5240cea26b78e27ea99964ade">stop</a> ()</td></tr>
<tr class="memdesc:a6515b9f5240cea26b78e27ea99964ade"><td class="mdescLeft">&#160;</td><td class="mdescRight">Blocks the calling thread until the constructor-started thread has finished; if the underlying <code>Task_engine</code> is not shared then first signals it to stop executing any further <code>Task</code>s, thus causing the constructor-started thread to in fact finish soon and hence this method to return soon.  <a href="classflow_1_1async_1_1Task__qing__thread.html#a6515b9f5240cea26b78e27ea99964ade">More...</a><br /></td></tr>
<tr class="separator:a6515b9f5240cea26b78e27ea99964ade"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="inherit_header pub_methods_classflow_1_1log_1_1Log__context"><td colspan="2" onclick="javascript:toggleInherit('pub_methods_classflow_1_1log_1_1Log__context')"><img src="closed.png" alt="-"/>&#160;Public Member Functions inherited from <a class="el" href="classflow_1_1log_1_1Log__context.html">flow::log::Log_context</a></td></tr>
<tr class="memitem:ae7100d2dd130d8f130e3e64fdb1f4fd9 inherit pub_methods_classflow_1_1log_1_1Log__context"><td class="memItemLeft" align="right" valign="top">&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classflow_1_1log_1_1Log__context.html#ae7100d2dd130d8f130e3e64fdb1f4fd9">Log_context</a> (<a class="el" href="classflow_1_1log_1_1Logger.html">Logger</a> *logger=0)</td></tr>
<tr class="memdesc:ae7100d2dd130d8f130e3e64fdb1f4fd9 inherit pub_methods_classflow_1_1log_1_1Log__context"><td class="mdescLeft">&#160;</td><td class="mdescRight">Constructs <a class="el" href="classflow_1_1log_1_1Log__context.html" title="Convenience class that simply stores a Logger and/or Component passed into a constructor; and returns...">Log_context</a> by storing the given pointer to a <a class="el" href="classflow_1_1log_1_1Logger.html" title="Interface that the user should implement, passing the implementing Logger into logging classes (Flow&#39;...">Logger</a> and a null <a class="el" href="classflow_1_1log_1_1Component.html" title="A light-weight class, each object storing a component payload encoding an enum value from enum type o...">Component</a>.  <a href="classflow_1_1log_1_1Log__context.html#ae7100d2dd130d8f130e3e64fdb1f4fd9">More...</a><br /></td></tr>
<tr class="separator:ae7100d2dd130d8f130e3e64fdb1f4fd9 inherit pub_methods_classflow_1_1log_1_1Log__context"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:af1ac7f30ab442c3c6aa6079335df6c9a inherit pub_methods_classflow_1_1log_1_1Log__context"><td class="memTemplParams" colspan="2">template&lt;typename Component_payload &gt; </td></tr>
<tr class="memitem:af1ac7f30ab442c3c6aa6079335df6c9a inherit pub_methods_classflow_1_1log_1_1Log__context"><td class="memTemplItemLeft" align="right" valign="top">&#160;</td><td class="memTemplItemRight" valign="bottom"><a class="el" href="classflow_1_1log_1_1Log__context.html#af1ac7f30ab442c3c6aa6079335df6c9a">Log_context</a> (<a class="el" href="classflow_1_1log_1_1Logger.html">Logger</a> *logger, Component_payload component_payload)</td></tr>
<tr class="memdesc:af1ac7f30ab442c3c6aa6079335df6c9a inherit pub_methods_classflow_1_1log_1_1Log__context"><td class="mdescLeft">&#160;</td><td class="mdescRight">Constructs <a class="el" href="classflow_1_1log_1_1Log__context.html" title="Convenience class that simply stores a Logger and/or Component passed into a constructor; and returns...">Log_context</a> by storing the given pointer to a <a class="el" href="classflow_1_1log_1_1Logger.html" title="Interface that the user should implement, passing the implementing Logger into logging classes (Flow&#39;...">Logger</a> and a new <a class="el" href="classflow_1_1log_1_1Component.html" title="A light-weight class, each object storing a component payload encoding an enum value from enum type o...">Component</a> storing the specified generically typed payload (an <code>enum</code> value).  <a href="classflow_1_1log_1_1Log__context.html#af1ac7f30ab442c3c6aa6079335df6c9a">More...</a><br /></td></tr>
<tr class="separator:af1ac7f30ab442c3c6aa6079335df6c9a inherit pub_methods_classflow_1_1log_1_1Log__context"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a5c57a7f44959a01ca9a1c948a6686cc0 inherit pub_methods_classflow_1_1log_1_1Log__context"><td class="memItemLeft" align="right" valign="top">&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classflow_1_1log_1_1Log__context.html#a5c57a7f44959a01ca9a1c948a6686cc0">Log_context</a> (const <a class="el" href="classflow_1_1log_1_1Log__context.html">Log_context</a> &amp;src)</td></tr>
<tr class="memdesc:a5c57a7f44959a01ca9a1c948a6686cc0 inherit pub_methods_classflow_1_1log_1_1Log__context"><td class="mdescLeft">&#160;</td><td class="mdescRight">Copy constructor that stores equal <code>Logger*</code> and <a class="el" href="classflow_1_1log_1_1Component.html" title="A light-weight class, each object storing a component payload encoding an enum value from enum type o...">Component</a> values as the source.  <a href="classflow_1_1log_1_1Log__context.html#a5c57a7f44959a01ca9a1c948a6686cc0">More...</a><br /></td></tr>
<tr class="separator:a5c57a7f44959a01ca9a1c948a6686cc0 inherit pub_methods_classflow_1_1log_1_1Log__context"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a3d4e624833d96bdafa1485ffff472509 inherit pub_methods_classflow_1_1log_1_1Log__context"><td class="memItemLeft" align="right" valign="top">&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classflow_1_1log_1_1Log__context.html#a3d4e624833d96bdafa1485ffff472509">Log_context</a> (<a class="el" href="classflow_1_1log_1_1Log__context.html">Log_context</a> &amp;&amp;src)</td></tr>
<tr class="memdesc:a3d4e624833d96bdafa1485ffff472509 inherit pub_methods_classflow_1_1log_1_1Log__context"><td class="mdescLeft">&#160;</td><td class="mdescRight">Move constructor that makes this equal to <code>src</code>, while the latter becomes as-if default-constructed.  <a href="classflow_1_1log_1_1Log__context.html#a3d4e624833d96bdafa1485ffff472509">More...</a><br /></td></tr>
<tr class="separator:a3d4e624833d96bdafa1485ffff472509 inherit pub_methods_classflow_1_1log_1_1Log__context"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a5d628315d5a93908d47a281980d3113e inherit pub_methods_classflow_1_1log_1_1Log__context"><td class="memItemLeft" align="right" valign="top"><a class="el" href="classflow_1_1log_1_1Log__context.html">Log_context</a> &amp;&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classflow_1_1log_1_1Log__context.html#a5d628315d5a93908d47a281980d3113e">operator=</a> (const <a class="el" href="classflow_1_1log_1_1Log__context.html">Log_context</a> &amp;src)</td></tr>
<tr class="memdesc:a5d628315d5a93908d47a281980d3113e inherit pub_methods_classflow_1_1log_1_1Log__context"><td class="mdescLeft">&#160;</td><td class="mdescRight">Assignment operator that behaves similarly to the copy constructor.  <a href="classflow_1_1log_1_1Log__context.html#a5d628315d5a93908d47a281980d3113e">More...</a><br /></td></tr>
<tr class="separator:a5d628315d5a93908d47a281980d3113e inherit pub_methods_classflow_1_1log_1_1Log__context"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:aae857197aecba8606c32296bc7bec308 inherit pub_methods_classflow_1_1log_1_1Log__context"><td class="memItemLeft" align="right" valign="top"><a class="el" href="classflow_1_1log_1_1Log__context.html">Log_context</a> &amp;&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classflow_1_1log_1_1Log__context.html#aae857197aecba8606c32296bc7bec308">operator=</a> (<a class="el" href="classflow_1_1log_1_1Log__context.html">Log_context</a> &amp;&amp;src)</td></tr>
<tr class="memdesc:aae857197aecba8606c32296bc7bec308 inherit pub_methods_classflow_1_1log_1_1Log__context"><td class="mdescLeft">&#160;</td><td class="mdescRight">Move assignment operator that behaves similarly to the move constructor.  <a href="classflow_1_1log_1_1Log__context.html#aae857197aecba8606c32296bc7bec308">More...</a><br /></td></tr>
<tr class="separator:aae857197aecba8606c32296bc7bec308 inherit pub_methods_classflow_1_1log_1_1Log__context"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:aa6bb8e4250586425631ef80063caf155 inherit pub_methods_classflow_1_1log_1_1Log__context"><td class="memItemLeft" align="right" valign="top">void&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classflow_1_1log_1_1Log__context.html#aa6bb8e4250586425631ef80063caf155">swap</a> (<a class="el" href="classflow_1_1log_1_1Log__context.html">Log_context</a> &amp;other)</td></tr>
<tr class="memdesc:aa6bb8e4250586425631ef80063caf155 inherit pub_methods_classflow_1_1log_1_1Log__context"><td class="mdescLeft">&#160;</td><td class="mdescRight">Swaps <a class="el" href="classflow_1_1log_1_1Logger.html" title="Interface that the user should implement, passing the implementing Logger into logging classes (Flow&#39;...">Logger</a> pointers and <a class="el" href="classflow_1_1log_1_1Component.html" title="A light-weight class, each object storing a component payload encoding an enum value from enum type o...">Component</a> objects held by <code>*this</code> and <code>other</code>.  <a href="classflow_1_1log_1_1Log__context.html#aa6bb8e4250586425631ef80063caf155">More...</a><br /></td></tr>
<tr class="separator:aa6bb8e4250586425631ef80063caf155 inherit pub_methods_classflow_1_1log_1_1Log__context"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:af4db395042b065b00398cd59845dcb4d inherit pub_methods_classflow_1_1log_1_1Log__context"><td class="memItemLeft" align="right" valign="top"><a class="el" href="classflow_1_1log_1_1Logger.html">Logger</a> *&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classflow_1_1log_1_1Log__context.html#af4db395042b065b00398cd59845dcb4d">get_logger</a> () const</td></tr>
<tr class="memdesc:af4db395042b065b00398cd59845dcb4d inherit pub_methods_classflow_1_1log_1_1Log__context"><td class="mdescLeft">&#160;</td><td class="mdescRight">Returns the stored <a class="el" href="classflow_1_1log_1_1Logger.html" title="Interface that the user should implement, passing the implementing Logger into logging classes (Flow&#39;...">Logger</a> pointer, particularly as many <code>FLOW_LOG_*()</code> macros expect.  <a href="classflow_1_1log_1_1Log__context.html#af4db395042b065b00398cd59845dcb4d">More...</a><br /></td></tr>
<tr class="separator:af4db395042b065b00398cd59845dcb4d inherit pub_methods_classflow_1_1log_1_1Log__context"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a8a5fef42dc2cedf3c0d1a6e83beb2948 inherit pub_methods_classflow_1_1log_1_1Log__context"><td class="memItemLeft" align="right" valign="top">const <a class="el" href="classflow_1_1log_1_1Component.html">Component</a> &amp;&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classflow_1_1log_1_1Log__context.html#a8a5fef42dc2cedf3c0d1a6e83beb2948">get_log_component</a> () const</td></tr>
<tr class="memdesc:a8a5fef42dc2cedf3c0d1a6e83beb2948 inherit pub_methods_classflow_1_1log_1_1Log__context"><td class="mdescLeft">&#160;</td><td class="mdescRight">Returns reference to the stored <a class="el" href="classflow_1_1log_1_1Component.html" title="A light-weight class, each object storing a component payload encoding an enum value from enum type o...">Component</a> object, particularly as many <code>FLOW_LOG_*()</code> macros expect.  <a href="classflow_1_1log_1_1Log__context.html#a8a5fef42dc2cedf3c0d1a6e83beb2948">More...</a><br /></td></tr>
<tr class="separator:a8a5fef42dc2cedf3c0d1a6e83beb2948 inherit pub_methods_classflow_1_1log_1_1Log__context"><td class="memSeparator" colspan="2">&#160;</td></tr>
</table><table class="memberdecls">
<tr class="heading"><td colspan="2"><h2 class="groupheader"><a id="pub-static-attribs" name="pub-static-attribs"></a>
Static Public Attributes</h2></td></tr>
<tr class="memitem:a981c21354bafc012748707a301b89d3e"><td class="memItemLeft" align="right" valign="top">static const int&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classflow_1_1async_1_1Task__qing__thread.html#a981c21354bafc012748707a301b89d3e">S_BAD_EXIT</a> = 1</td></tr>
<tr class="memdesc:a981c21354bafc012748707a301b89d3e"><td class="mdescLeft">&#160;</td><td class="mdescRight"><code>exit()</code> code returned to OS in the event <a class="el" href="classflow_1_1async_1_1Task__qing__thread.html" title="Internally used building block of various concrete Concurrent_task_loop subclasses that encapsulates ...">Task_qing_thread</a> chooses to <code>exit()</code> the entire program (as of this writing, this occurs on uncaught exception by a user task).  <a href="classflow_1_1async_1_1Task__qing__thread.html#a981c21354bafc012748707a301b89d3e">More...</a><br /></td></tr>
<tr class="separator:a981c21354bafc012748707a301b89d3e"><td class="memSeparator" colspan="2">&#160;</td></tr>
</table><table class="memberdecls">
<tr class="heading"><td colspan="2"><h2 class="groupheader"><a id="pri-attribs" name="pri-attribs"></a>
Private Attributes</h2></td></tr>
<tr class="memitem:a1f4a96efdc1820ddbb4a4bf49c0d38e6"><td class="memItemLeft" align="right" valign="top"><a class="el" href="namespaceflow_1_1async.html#a968806f54b14c697fd76b3339a2bdbbf">Task_engine_ptr</a>&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classflow_1_1async_1_1Task__qing__thread.html#a1f4a96efdc1820ddbb4a4bf49c0d38e6">m_task_engine</a></td></tr>
<tr class="memdesc:a1f4a96efdc1820ddbb4a4bf49c0d38e6"><td class="mdescLeft">&#160;</td><td class="mdescRight">See <a class="el" href="classflow_1_1async_1_1Task__qing__thread.html#aaf0191625ae2613a7351dc0515398903" title="Returns pointer to util::Task_engine such that post()ing to it will cause the subsequent asynchronous...">task_engine()</a>.  <a href="classflow_1_1async_1_1Task__qing__thread.html#a1f4a96efdc1820ddbb4a4bf49c0d38e6">More...</a><br /></td></tr>
<tr class="separator:a1f4a96efdc1820ddbb4a4bf49c0d38e6"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a0a80c87ce824a15fb84a73d99f5d61ac"><td class="memItemLeft" align="right" valign="top"><a class="el" href="classbool.html">bool</a>&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classflow_1_1async_1_1Task__qing__thread.html#a0a80c87ce824a15fb84a73d99f5d61ac">m_own_task_engine</a></td></tr>
<tr class="memdesc:a0a80c87ce824a15fb84a73d99f5d61ac"><td class="mdescLeft">&#160;</td><td class="mdescRight">See constructor.  <a href="classflow_1_1async_1_1Task__qing__thread.html#a0a80c87ce824a15fb84a73d99f5d61ac">More...</a><br /></td></tr>
<tr class="separator:a0a80c87ce824a15fb84a73d99f5d61ac"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a75b218e1b5f137ead984588107ef02b0"><td class="memItemLeft" align="right" valign="top">boost::movelib::unique_ptr&lt; <a class="el" href="namespaceflow_1_1util.html#af030c3119f060a9630afca31098a78a5">util::Thread</a> &gt;&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classflow_1_1async_1_1Task__qing__thread.html#a75b218e1b5f137ead984588107ef02b0">m_worker_thread</a></td></tr>
<tr class="memdesc:a75b218e1b5f137ead984588107ef02b0"><td class="mdescLeft">&#160;</td><td class="mdescRight">Thread created in constructor. Not-a-thread after <a class="el" href="classflow_1_1async_1_1Task__qing__thread.html#a6515b9f5240cea26b78e27ea99964ade" title="Blocks the calling thread until the constructor-started thread has finished; if the underlying Task_e...">stop()</a>; not not-a-thread before <a class="el" href="classflow_1_1async_1_1Task__qing__thread.html#a6515b9f5240cea26b78e27ea99964ade" title="Blocks the calling thread until the constructor-started thread has finished; if the underlying Task_e...">stop()</a>.  <a href="classflow_1_1async_1_1Task__qing__thread.html#a75b218e1b5f137ead984588107ef02b0">More...</a><br /></td></tr>
<tr class="separator:a75b218e1b5f137ead984588107ef02b0"><td class="memSeparator" colspan="2">&#160;</td></tr>
</table>
<a name="details" id="details"></a><h2 class="groupheader">Detailed Description</h2>
<div class="textblock"><p >Internally used building block of various concrete <a class="el" href="classflow_1_1async_1_1Concurrent__task__loop.html" title="The core flow::async interface, providing an optionally multi-threaded thread pool onto which runnabl...">Concurrent_task_loop</a> subclasses that encapsulates a thread that spawns at construction time and a dedicated-or-shared <a class="el" href="namespaceflow_1_1util.html#ac3e89a8a271b0ddc76ac2a0ce488dea4" title="Short-hand for boost.asio event service, the central class of boost.asio.">util::Task_engine</a> (a/k/a boost.asio <code>io_context</code>) <code>run()</code>ning in that new thread. </p>
<p >This class:</p><ul>
<li>At construction:<ul>
<li>Takes a ref-counted reference to an existing <a class="el" href="namespaceflow_1_1util.html#ac3e89a8a271b0ddc76ac2a0ce488dea4" title="Short-hand for boost.asio event service, the central class of boost.asio.">util::Task_engine</a>, which may be fresh of posted tasks or not; shared with another <a class="el" href="classflow_1_1async_1_1Task__qing__thread.html" title="Internally used building block of various concrete Concurrent_task_loop subclasses that encapsulates ...">Task_qing_thread</a> or not.</li>
<li>Starts a thread, ultimately executing an indefinitely-running <code>Task_engine::run()</code>, thus either comprising the single thread executing tasks from that <code>Task_engine</code>; or joining a pool of such threads.<ul>
<li><code>post(*(this-&gt;<a class="el" href="classflow_1_1async_1_1Task__qing__thread.html#aaf0191625ae2613a7351dc0515398903" title="Returns pointer to util::Task_engine such that post()ing to it will cause the subsequent asynchronous...">task_engine()</a>), F)</code> can be used to queue up tasks to execute; and any already-queued work on <code>*(this-&gt;<a class="el" href="classflow_1_1async_1_1Task__qing__thread.html#aaf0191625ae2613a7351dc0515398903" title="Returns pointer to util::Task_engine such that post()ing to it will cause the subsequent asynchronous...">task_engine()</a>)</code> may execute in this new thread as well. (This is all thread-safe due to the thread-safe nature of boost.asio <a class="el" href="namespaceflow_1_1util.html#ac3e89a8a271b0ddc76ac2a0ce488dea4" title="Short-hand for boost.asio event service, the central class of boost.asio.">util::Task_engine</a> posting, including across thread creation and destruction.)</li>
</ul>
</li>
</ul>
</li>
<li>Ends* the thread and "joins" it in destructor.<ul>
<li>Can also do this earlier (but still irreversibly) via the <a class="el" href="classflow_1_1async_1_1Task__qing__thread.html#a6515b9f5240cea26b78e27ea99964ade" title="Blocks the calling thread until the constructor-started thread has finished; if the underlying Task_e...">stop()</a> API.</li>
<li>*If the <code>Task_engine</code> is shared with other <code><a class="el" href="classflow_1_1async_1_1Task__qing__thread.html" title="Internally used building block of various concrete Concurrent_task_loop subclasses that encapsulates ...">Task_qing_thread</a></code>s, per <code>own_task_engine</code> ctor arg, then the <code>Task_engine::stop()</code> call must be executed by outside code instead.</li>
</ul>
</li>
<li>Exits the program (!) if a task posted via <a class="el" href="classflow_1_1async_1_1Task__qing__thread.html#aaf0191625ae2613a7351dc0515398903" title="Returns pointer to util::Task_engine such that post()ing to it will cause the subsequent asynchronous...">task_engine()</a> throws an uncaught exception.</li>
<li>Provides access to low-level underlying <a class="el" href="namespaceflow_1_1util.html#af030c3119f060a9630afca31098a78a5" title="Short-hand for standard thread class.">util::Thread</a> via <a class="el" href="classflow_1_1async_1_1Task__qing__thread.html#a3f9a0071880455c00a993d36c6040ae5" title="Returns the util::Thread – a thin wrapper around the native OS thread handle – corresponding to the w...">raw_worker_thread()</a>; see <a class="el" href="namespaceflow_1_1async.html#a3e200db7e5375de21d2568004a85dcad" title="Assuming the same situation as documented for optimal_worker_thread_count_per_pool(),...">async::optimize_pinning_in_thread_pool()</a>. Note <a class="el" href="namespaceflow_1_1util.html#af030c3119f060a9630afca31098a78a5" title="Short-hand for standard thread class.">util::Thread</a> in turn allows direct native access to the OS thread object (pthread handle, or whatever).</li>
</ul>
<h3>Design rationale</h3>
<p ><a class="el" href="classflow_1_1async_1_1Task__qing__thread.html#abb03d1b5f50a2b6148da27139a2391da" title="Constructs object, immediately spawning new (worker) thread, memorizing a ref-counted reference to th...">Task_qing_thread()</a> constructor doc header contains discussion worth reading. </p>

<p class="definition">Definition at line <a class="el" href="task__qing__thread_8hpp_source.html#l00059">59</a> of file <a class="el" href="task__qing__thread_8hpp_source.html">task_qing_thread.hpp</a>.</p>
</div><h2 class="groupheader">Constructor &amp; Destructor Documentation</h2>
<a id="abb03d1b5f50a2b6148da27139a2391da" name="abb03d1b5f50a2b6148da27139a2391da"></a>
<h2 class="memtitle"><span class="permalink"><a href="#abb03d1b5f50a2b6148da27139a2391da">&#9670;&nbsp;</a></span>Task_qing_thread()</h2>

<div class="memitem">
<div class="memproto">
<table class="mlabels">
  <tr>
  <td class="mlabels-left">
      <table class="memname">
        <tr>
          <td class="memname">flow::async::Task_qing_thread::Task_qing_thread </td>
          <td>(</td>
          <td class="paramtype"><a class="el" href="classflow_1_1log_1_1Logger.html">flow::log::Logger</a> *&#160;</td>
          <td class="paramname"><em>logger_ptr</em>, </td>
        </tr>
        <tr>
          <td class="paramkey"></td>
          <td></td>
          <td class="paramtype"><a class="el" href="namespaceflow_1_1util.html#ae4dc52186797094b3040379ff19124c9">util::String_view</a>&#160;</td>
          <td class="paramname"><em>nickname</em>, </td>
        </tr>
        <tr>
          <td class="paramkey"></td>
          <td></td>
          <td class="paramtype">const <a class="el" href="namespaceflow_1_1async.html#a968806f54b14c697fd76b3339a2bdbbf">Task_engine_ptr</a> &amp;&#160;</td>
          <td class="paramname"><em>task_engine</em>, </td>
        </tr>
        <tr>
          <td class="paramkey"></td>
          <td></td>
          <td class="paramtype"><a class="el" href="classbool.html">bool</a>&#160;</td>
          <td class="paramname"><em>own_task_engine</em>, </td>
        </tr>
        <tr>
          <td class="paramkey"></td>
          <td></td>
          <td class="paramtype">boost::promise&lt; void &gt; *&#160;</td>
          <td class="paramname"><em>done_promise_else_block</em> = <code>0</code>, </td>
        </tr>
        <tr>
          <td class="paramkey"></td>
          <td></td>
          <td class="paramtype"><a class="el" href="namespaceflow_1_1async.html#af35fb65bdea1a3a92929ec2c4a6a6b72">Task</a> &amp;&amp;&#160;</td>
          <td class="paramname"><em>init_func_or_empty</em> = <code><a class="el" href="namespaceflow_1_1async.html#af35fb65bdea1a3a92929ec2c4a6a6b72">Task</a>()</code>&#160;</td>
        </tr>
        <tr>
          <td></td>
          <td>)</td>
          <td></td><td></td>
        </tr>
      </table>
  </td>
  <td class="mlabels-right">
<span class="mlabels"><span class="mlabel">explicit</span></span>  </td>
  </tr>
</table>
</div><div class="memdoc">

<p>Constructs object, immediately spawning new (worker) thread, memorizing a ref-counted reference to the provided <a class="el" href="namespaceflow_1_1util.html#ac3e89a8a271b0ddc76ac2a0ce488dea4" title="Short-hand for boost.asio event service, the central class of boost.asio.">util::Task_engine</a> which may or may not be a fresh one and meant to be shared with other <code><a class="el" href="classflow_1_1async_1_1Task__qing__thread.html" title="Internally used building block of various concrete Concurrent_task_loop subclasses that encapsulates ...">Task_qing_thread</a></code>s or exclusively by this one. </p>
<p >The post-condition of this constructor is:</p><ul>
<li>If <code>done_promise_else_block</code> is null, it's:<ul>
<li>The new thread has started.</li>
<li>If <code>init_func_or_empty</code> is not <code>.empty()</code>, then: <code>init_func_or_empty()</code> ran <em>first-thing</em> in that thread and returned.<ul>
<li>Note: This is a useful guarantee, if, say, you need to perform some privileged actions at thread setup; once this post-condition holds, it is safe to drop privileges.</li>
</ul>
</li>
<li>The thread is ready to participate in task-posting via <code>post(*this-&gt;<a class="el" href="classflow_1_1async_1_1Task__qing__thread.html#aaf0191625ae2613a7351dc0515398903" title="Returns pointer to util::Task_engine such that post()ing to it will cause the subsequent asynchronous...">task_engine()</a>, F)</code> and similar.</li>
</ul>
</li>
<li>If <code>done_promise_else_block</code> is <em>not</em> null, it's:<ul>
<li>None. However, if one executes <code>done_promise_else_block-&gt;get_future().wait()</code>, upon return from that statement, the above if-<code>done_promise_else_block</code>-is-null post-conditions will hold.</li>
</ul>
</li>
</ul>
<dl class="section note"><dt>Note</dt><dd><code>!done_promise_else_block</code> mode is typical. Just wait for construction, then <code>post()</code> away. The other mode is helpful when one has an N-thread pool and wants each <a class="el" href="classflow_1_1async_1_1Task__qing__thread.html" title="Internally used building block of various concrete Concurrent_task_loop subclasses that encapsulates ...">Task_qing_thread</a> to initialize concurrently with the others instead of serially. Then one can pass in N <code>promise</code>s to N <a class="el" href="classflow_1_1async_1_1Task__qing__thread.html" title="Internally used building block of various concrete Concurrent_task_loop subclasses that encapsulates ...">Task_qing_thread</a> ctor calls, then wait on the N respective <code>unique_future</code>s.</dd>
<dd>
When creating the <a class="el" href="namespaceflow_1_1util.html#ac3e89a8a271b0ddc76ac2a0ce488dea4" title="Short-hand for boost.asio event service, the central class of boost.asio.">util::Task_engine</a> <code>task_engine</code>, it is usually a good idea for perf to pass the concurrency-hint arg value 1 (one) if either <code>own_task_engine == true</code>, or the overall thread pool simply will have but 1 thread. This will allow boost.asio to optimize internal locking and such.</dd></dl>
<p>The worker thread started by each <a class="el" href="classflow_1_1async_1_1Task__qing__thread.html" title="Internally used building block of various concrete Concurrent_task_loop subclasses that encapsulates ...">Task_qing_thread</a> constructor will exit upon any uncaught exception by one of the user-supplied <code>Task</code>s <code>post()</code>ed onto it subsequently. If this occurs, the handler will <code>exit()</code> the entire program with a non-zero code after logging (to <code>*logger_ptr</code>) the exception message. (It is informally recommended that all other threads in the application do the same.)</p>
<p >Assuming no such uncaught exception is thrown, the thread will run until <a class="el" href="classflow_1_1async_1_1Task__qing__thread.html#a6515b9f5240cea26b78e27ea99964ade" title="Blocks the calling thread until the constructor-started thread has finished; if the underlying Task_e...">stop()</a> or the destructor is called and returns.</p>
<h3>Basic concept discussion: To share or not to share (a <code>Task_engine</code>)?</h3>
<p >The choice of <code>own_task_engine</code> flag, as of this writing, does not actually affect much of <code>*this</code> behavior. If <code>true</code>, then you're saying this is the only thread to run tasks on the <code>Task_engine</code> (call it E). If <code>false</code>, it may be shared with other threads. In practice, though, as of this writing, this only controls whether <a class="el" href="classflow_1_1async_1_1Task__qing__thread.html#a6515b9f5240cea26b78e27ea99964ade" title="Blocks the calling thread until the constructor-started thread has finished; if the underlying Task_e...">stop()</a> will perform <code>E-&gt;<a class="el" href="classflow_1_1async_1_1Task__qing__thread.html#a6515b9f5240cea26b78e27ea99964ade" title="Blocks the calling thread until the constructor-started thread has finished; if the underlying Task_e...">stop()</a></code> (which causes all <code>E-&gt;run()</code>s to return and hence threads to soon exit) for you (<code>true</code>), or you must do it for the shared E yourself (which has other objects like <code>*this</code> associated with it). Either way, E can be used before or after <code>*this</code> thread runs in whatever way one prefers, including: one can pre-queueing tasks (via <code>post(*E, F)</code> and such) for it to join in executing in new thread; one can inherit any not-yet-executed tasks after <a class="el" href="classflow_1_1async_1_1Task__qing__thread.html#a6515b9f5240cea26b78e27ea99964ade" title="Blocks the calling thread until the constructor-started thread has finished; if the underlying Task_e...">stop()</a>, to execute them in some other thread/run().</p>
<p >That said, despite the small practical impact in <em>this</em> class, the decision of whether to assign one <a class="el" href="classflow_1_1async_1_1Task__qing__thread.html" title="Internally used building block of various concrete Concurrent_task_loop subclasses that encapsulates ...">Task_qing_thread</a> (and hence <a class="el" href="namespaceflow_1_1util.html#af030c3119f060a9630afca31098a78a5" title="Short-hand for standard thread class.">util::Thread</a> and hence native thread) to a <code>Task_engine</code> in one-to-one fashion, versus sharing the latter with more <code><a class="el" href="classflow_1_1async_1_1Task__qing__thread.html" title="Internally used building block of various concrete Concurrent_task_loop subclasses that encapsulates ...">Task_qing_thread</a></code>s, is a central one to your design. It is central to specifying the pattern of how <code>post()</code>ed <code>Task</code>s are spread across actual threads in a pool. In particular, if it's <code>true</code> (not shared), then one <em>must</em> select a specific <a class="el" href="classflow_1_1async_1_1Task__qing__thread.html" title="Internally used building block of various concrete Concurrent_task_loop subclasses that encapsulates ...">Task_qing_thread</a> (and, therefore, its corresponding worker thread) before actually <code>post()</code>ing; otherwise it will be selected intelligently by boost.asio. On the other hand, if it's <code>false</code> (shared), then to guarantee two tasks FG will not execute concurrently (&lt;= desirable if they're assigned to one <a class="el" href="namespaceflow_1_1async.html#a024042c64b7dc544a7a5587afa4b1949" title="An object of this opaque type represents a collection of 1 or more async::Task, past or future,...">async::Op</a>) one must probably use a <a class="el" href="namespaceflow_1_1util.html#aa59354ab408e978c8a7bda1a4706924e" title="Short-hand for boost.asio strand, an ancillary class that works with Task_engine for advanced task sc...">util::Strand</a>. Meanwhile if it IS <code>true</code> (not shared), then one can simply guarantee it by posting onto the same <a class="el" href="classflow_1_1async_1_1Task__qing__thread.html" title="Internally used building block of various concrete Concurrent_task_loop subclasses that encapsulates ...">Task_qing_thread</a> (i.e., worker thread)... which is straightforward but theoretically worse at using available time slices across threads. It's worse that way, but on the other hand thread-to-core-pinning is arguably more predictable in terms of ultimate effect on performance when <code>Strand</code>s aren't used. Plus it might cause thread-caching perf increases.</p>
<p >Very informally, and perhaps arguably, the <code>true</code> (do-not-share-engine) mode is the legacy way and is how certain entrenched legacy daemons do it; the <code>false</code> (share-engine-among-threads) is the common-sense boost.asio-leveraging way which might be the default for new applications; but it depends also on perf analysis of thread caching benefits of the <code>true</code> way as well.</p>
<h3>Rationale/history</h3>
<p >Also informally: The hairiness of forcing the user to have to make this decision, and then write potentially <code>if</code>-laden code that subsequently actually posts tasks, is a chief motivation for abstracting such details behind the interfaces <a class="el" href="classflow_1_1async_1_1Concurrent__task__loop.html" title="The core flow::async interface, providing an optionally multi-threaded thread pool onto which runnabl...">Concurrent_task_loop</a> and <a class="el" href="namespaceflow_1_1async.html#a024042c64b7dc544a7a5587afa4b1949" title="An object of this opaque type represents a collection of 1 or more async::Task, past or future,...">async::Op</a>. Then the user gets to just post <code>Task</code>s, optionally tagged with <code>Op</code>s to prevent unwanted concurrency, while the aforementioned interfaces will deal with the different ways of using <a class="el" href="classflow_1_1async_1_1Task__qing__thread.html" title="Internally used building block of various concrete Concurrent_task_loop subclasses that encapsulates ...">Task_qing_thread</a>. Therefore, <a class="el" href="classflow_1_1async_1_1Task__qing__thread.html" title="Internally used building block of various concrete Concurrent_task_loop subclasses that encapsulates ...">Task_qing_thread</a> is a detail/ class not to be used by or exposed to the user.</p>
<p >Historically, a certain proof of concept (PoC) started out by having "user" code deal with <code>Task_engine</code>s directly, quickly morphing to wrap them with <a class="el" href="classflow_1_1async_1_1Task__qing__thread.html" title="Internally used building block of various concrete Concurrent_task_loop subclasses that encapsulates ...">Task_qing_thread</a> for ease of use. Then once this PoC desired to have knobs controlling how tasks are scheduled across threads, without having the "user" code worry about it after initial thread-pool setup, <a class="el" href="classflow_1_1async_1_1Task__qing__thread.html" title="Internally used building block of various concrete Concurrent_task_loop subclasses that encapsulates ...">Task_qing_thread</a> was moved from the public area into detail/, and <a class="el" href="classflow_1_1async_1_1Concurrent__task__loop.html" title="The core flow::async interface, providing an optionally multi-threaded thread pool onto which runnabl...">Concurrent_task_loop</a> was born (along with with helper type <a class="el" href="namespaceflow_1_1async.html#a024042c64b7dc544a7a5587afa4b1949" title="An object of this opaque type represents a collection of 1 or more async::Task, past or future,...">async::Op</a>).</p>
<h3>Logging subtlety</h3>
<p >For convenience, as promised by at least <a class="el" href="classflow_1_1async_1_1Cross__thread__task__loop.html#a5705e34163dec8463a30361bdb2fa83f" title="Implements superclass API.">Cross_thread_task_loop::start()</a> doc header: If user has specified a Config::this_thread_verbosity_override() setting (to reduce or increase log volume temporarily), then we take it upon ourselves to apply this setting to the spawned thread during exactly the following times:</p><ul>
<li>Any startup logging in the spawned thread, by <code>*this</code>.</li>
<li>Any shutdown logging in the spawned thread, by <code>*this</code>, after <a class="el" href="classflow_1_1async_1_1Task__qing__thread.html#a6515b9f5240cea26b78e27ea99964ade" title="Blocks the calling thread until the constructor-started thread has finished; if the underlying Task_e...">stop()</a> triggers thread exit.</li>
</ul>
<dl class="params"><dt>Parameters</dt><dd>
  <table class="params">
    <tr><td class="paramname">logger_ptr</td><td>Logger to use for subsequently logging. </td></tr>
    <tr><td class="paramname">nickname</td><td>Brief, human-readable nickname of the new thread pool, as of this writing for logging only. </td></tr>
    <tr><td class="paramname">task_engine</td><td>The <a class="el" href="namespaceflow_1_1util.html#ac3e89a8a271b0ddc76ac2a0ce488dea4" title="Short-hand for boost.asio event service, the central class of boost.asio.">util::Task_engine</a> E such that the body of the new thread will be essentially <code>E-&gt;run()</code>. </td></tr>
    <tr><td class="paramname">own_task_engine</td><td>Essentially, <code>true</code> if you do not wish to share <code>*task_engine</code> with other <code><a class="el" href="classflow_1_1async_1_1Task__qing__thread.html" title="Internally used building block of various concrete Concurrent_task_loop subclasses that encapsulates ...">Task_qing_thread</a></code>s; <code>false</code> if you do wish to share it with other such threads. See more detailed notes above. Also see <a class="el" href="classflow_1_1async_1_1Task__qing__thread.html#a6515b9f5240cea26b78e27ea99964ade" title="Blocks the calling thread until the constructor-started thread has finished; if the underlying Task_e...">stop()</a>. </td></tr>
    <tr><td class="paramname">init_func_or_empty</td><td>If not <code>.empty()</code>, <code>init_func_or_empty()</code> shall execute first-thing in the new thread, before internal code begins the thread's participation in the <code>*task_engine</code> event loop (i.e., before task_engine-&gt;run()). </td></tr>
    <tr><td class="paramname">done_promise_else_block</td><td>If null, ctor will block until the thread has started and is ready to participate in <code><a class="el" href="classflow_1_1async_1_1Task__qing__thread.html#aaf0191625ae2613a7351dc0515398903" title="Returns pointer to util::Task_engine such that post()ing to it will cause the subsequent asynchronous...">task_engine()</a>-&gt;post()</code>ing (etc.; see above text). If not null, then it will kick things off asynchronously and satisfy the <code>promise *done_promise_else_block</code> once the thread has started and is ready to p... you get the idea. </td></tr>
  </table>
  </dd>
</dl>

<p class="definition">Definition at line <a class="el" href="task__qing__thread_8cpp_source.html#l00037">37</a> of file <a class="el" href="task__qing__thread_8cpp_source.html">task_qing_thread.cpp</a>.</p>

<p class="reference">References <a class="el" href="log_8cpp_source.html#l00271">flow::log::beautify_chrono_logger_this_thread()</a>, <a class="el" href="log_8hpp_source.html#l00197">FLOW_LOG_INFO</a>, <a class="el" href="log_8hpp_source.html#l00227">FLOW_LOG_TRACE</a>, <a class="el" href="log_8cpp_source.html#l00217">flow::log::Log_context::get_logger()</a>, <a class="el" href="task__qing__thread_8hpp_source.html#l00268">m_own_task_engine</a>, <a class="el" href="task__qing__thread_8hpp_source.html#l00265">m_task_engine</a>, <a class="el" href="task__qing__thread_8hpp_source.html#l00271">m_worker_thread</a>, and <a class="el" href="namespaceflow_1_1async.html#a0a06794b16b72f2829ce3353557c8485a4d7a5700444c0570af37b1f9bcc6eb1f">flow::async::S_ASYNC</a>.</p>
<div class="dynheader">
Here is the call graph for this function:</div>
<div class="dyncontent">
<div class="center"><iframe scrolling="no" frameborder="0" src="classflow_1_1async_1_1Task__qing__thread_abb03d1b5f50a2b6148da27139a2391da_cgraph.svg" width="966" height="203"><p><b>This browser is not able to show SVG: try Firefox, Chrome, Safari, or Opera instead.</b></p></iframe>
</div>
</div>

</div>
</div>
<a id="abd3046b2dee9df486ba2710cb0d6b2e3" name="abd3046b2dee9df486ba2710cb0d6b2e3"></a>
<h2 class="memtitle"><span class="permalink"><a href="#abd3046b2dee9df486ba2710cb0d6b2e3">&#9670;&nbsp;</a></span>~Task_qing_thread()</h2>

<div class="memitem">
<div class="memproto">
      <table class="memname">
        <tr>
          <td class="memname">flow::async::Task_qing_thread::~Task_qing_thread </td>
          <td>(</td>
          <td class="paramname"></td><td>)</td>
          <td></td>
        </tr>
      </table>
</div><div class="memdoc">

<p><a class="el" href="classflow_1_1async_1_1Task__qing__thread.html#a6515b9f5240cea26b78e27ea99964ade" title="Blocks the calling thread until the constructor-started thread has finished; if the underlying Task_e...">stop()</a>, followed by forgetting the <code>Task_engine</code> returned by <a class="el" href="classflow_1_1async_1_1Task__qing__thread.html#aaf0191625ae2613a7351dc0515398903" title="Returns pointer to util::Task_engine such that post()ing to it will cause the subsequent asynchronous...">task_engine()</a>; the latter action may destroy that <code>Task_engine</code> synchronously. </p>
<p >In particular <a class="el" href="classflow_1_1async_1_1Task__qing__thread.html#aaf0191625ae2613a7351dc0515398903" title="Returns pointer to util::Task_engine such that post()ing to it will cause the subsequent asynchronous...">task_engine()</a> shall be destroyed by this destructor, unless you've saved a copy of that <code>shared_ptr</code> elsewhere (particularly in <code>own_task_engine == false</code> mode in ctor, it is likely to be saved in another <a class="el" href="classflow_1_1async_1_1Task__qing__thread.html" title="Internally used building block of various concrete Concurrent_task_loop subclasses that encapsulates ...">Task_qing_thread</a>).</p>
<p >Since <a class="el" href="classflow_1_1async_1_1Task__qing__thread.html#a6515b9f5240cea26b78e27ea99964ade" title="Blocks the calling thread until the constructor-started thread has finished; if the underlying Task_e...">stop()</a> has the post-condition that the thread has been joined, the same post-condition holds for this destructor. It is, of course, safe to call this destructor after already having called <a class="el" href="classflow_1_1async_1_1Task__qing__thread.html#a6515b9f5240cea26b78e27ea99964ade" title="Blocks the calling thread until the constructor-started thread has finished; if the underlying Task_e...">stop()</a>.</p>
<dl class="section see"><dt>See also</dt><dd><a class="el" href="classflow_1_1async_1_1Task__qing__thread.html#a6515b9f5240cea26b78e27ea99964ade" title="Blocks the calling thread until the constructor-started thread has finished; if the underlying Task_e...">stop()</a> which is useful when you want the thread to exit/be joined, but the underlying <code>Task_engine</code> must continue to exist for a bit; in particular <code>post()</code> on it would execute but do nothing. Then once you've ensured no more such <code>post()</code>s are forthcoming, and hence it's safe, "finish the job" by destroying <code>*this</code>.</dd>
<dd>
<a class="el" href="classflow_1_1async_1_1Task__qing__thread.html#aaf0191625ae2613a7351dc0515398903" title="Returns pointer to util::Task_engine such that post()ing to it will cause the subsequent asynchronous...">task_engine()</a> through which one can obtain a ref-counted <a class="el" href="namespaceflow_1_1util.html#ac3e89a8a271b0ddc76ac2a0ce488dea4" title="Short-hand for boost.asio event service, the central class of boost.asio.">util::Task_engine</a>, for example with the idea to have another thread <code><a class="el" href="classflow_1_1async_1_1Task__qing__thread.html#aaf0191625ae2613a7351dc0515398903" title="Returns pointer to util::Task_engine such that post()ing to it will cause the subsequent asynchronous...">task_engine()</a>-&gt;run()</code>, thus inheriting any queued work/tasks and able to enqueue and execute future ones. </dd></dl>

<p class="definition">Definition at line <a class="el" href="task__qing__thread_8cpp_source.html#l00248">248</a> of file <a class="el" href="task__qing__thread_8cpp_source.html">task_qing_thread.cpp</a>.</p>

<p class="reference">References <a class="el" href="log_8hpp_source.html#l00197">FLOW_LOG_INFO</a>, <a class="el" href="log_8hpp_source.html#l00227">FLOW_LOG_TRACE</a>, and <a class="el" href="task__qing__thread_8cpp_source.html#l00259">stop()</a>.</p>
<div class="dynheader">
Here is the call graph for this function:</div>
<div class="dyncontent">
<div class="center"><iframe scrolling="no" frameborder="0" src="classflow_1_1async_1_1Task__qing__thread_abd3046b2dee9df486ba2710cb0d6b2e3_cgraph.svg" width="379" height="47"><p><b>This browser is not able to show SVG: try Firefox, Chrome, Safari, or Opera instead.</b></p></iframe>
</div>
</div>

</div>
</div>
<h2 class="groupheader">Member Function Documentation</h2>
<a id="a3f9a0071880455c00a993d36c6040ae5" name="a3f9a0071880455c00a993d36c6040ae5"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a3f9a0071880455c00a993d36c6040ae5">&#9670;&nbsp;</a></span>raw_worker_thread()</h2>

<div class="memitem">
<div class="memproto">
      <table class="memname">
        <tr>
          <td class="memname"><a class="el" href="namespaceflow_1_1util.html#af030c3119f060a9630afca31098a78a5">util::Thread</a> * flow::async::Task_qing_thread::raw_worker_thread </td>
          <td>(</td>
          <td class="paramname"></td><td>)</td>
          <td></td>
        </tr>
      </table>
</div><div class="memdoc">

<p>Returns the <a class="el" href="namespaceflow_1_1util.html#af030c3119f060a9630afca31098a78a5" title="Short-hand for standard thread class.">util::Thread</a> &ndash; a thin wrapper around the native OS thread handle &ndash; corresponding to the worker thread started in constructor. </p>
<p >The intended use of this is to set thread attributes (such as processor-core affinity) in a way that won't affect/disturb the concurrently executing thread's ability to execute tasks; meaning one might grab its native ID and then set some affinity attribute, but it wouldn't (say) suspend the thread or join it. Slightly informally, then: any such steps ("such" being the informal part) lead to undefined behavior.</p>
<dl class="section return"><dt>Returns</dt><dd>Pointer to <code>Thread</code>, not null. Guaranteed valid until destructor is invoked; guaranteed to be not-a-thread after <a class="el" href="classflow_1_1async_1_1Task__qing__thread.html#a6515b9f5240cea26b78e27ea99964ade" title="Blocks the calling thread until the constructor-started thread has finished; if the underlying Task_e...">stop()</a> and not not-a-thread before it. </dd></dl>

<p class="definition">Definition at line <a class="el" href="task__qing__thread_8cpp_source.html#l00309">309</a> of file <a class="el" href="task__qing__thread_8cpp_source.html">task_qing_thread.cpp</a>.</p>

<p class="reference">References <a class="el" href="task__qing__thread_8hpp_source.html#l00271">m_worker_thread</a>.</p>

</div>
</div>
<a id="a6515b9f5240cea26b78e27ea99964ade" name="a6515b9f5240cea26b78e27ea99964ade"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a6515b9f5240cea26b78e27ea99964ade">&#9670;&nbsp;</a></span>stop()</h2>

<div class="memitem">
<div class="memproto">
      <table class="memname">
        <tr>
          <td class="memname">void flow::async::Task_qing_thread::stop </td>
          <td>(</td>
          <td class="paramname"></td><td>)</td>
          <td></td>
        </tr>
      </table>
</div><div class="memdoc">

<p>Blocks the calling thread until the constructor-started thread has finished; if the underlying <code>Task_engine</code> is not shared then first signals it to stop executing any further <code>Task</code>s, thus causing the constructor-started thread to in fact finish soon and hence this method to return soon. </p>
<p >After <a class="el" href="classflow_1_1async_1_1Task__qing__thread.html#a6515b9f5240cea26b78e27ea99964ade" title="Blocks the calling thread until the constructor-started thread has finished; if the underlying Task_e...">stop()</a> has returned once already, <a class="el" href="classflow_1_1async_1_1Task__qing__thread.html#a6515b9f5240cea26b78e27ea99964ade" title="Blocks the calling thread until the constructor-started thread has finished; if the underlying Task_e...">stop()</a> will immediately return. Concurrently executing <a class="el" href="classflow_1_1async_1_1Task__qing__thread.html#a6515b9f5240cea26b78e27ea99964ade" title="Blocks the calling thread until the constructor-started thread has finished; if the underlying Task_e...">stop()</a> from 2+ different threads leads to undefined behavior.</p>
<p >In effect: If we own the <code>Task_engine</code> (<code>own_task_engine == true</code> in constructor), this method causes the <code>Task_engine</code> to stop executing tasks ASAP and then waits as long as necessary for the thread to exit; then returns. This will be fast if <code>Task</code>s are well behaved (do not block).</p>
<p >In effect: If we share an external <code>Task_engine</code> (<code>own_task_engine == false</code> in constructor), this method simply waits for the thread to exit as long as needed. Hence the caller must trigger the shared <code>Task_engine</code> to exit this thread's <code>Task_engine::run()</code>. (In particular, <code>Task_engine::stop()</code> will do this.) Otherwise this method will block until then.</p>
<p >The key fact is that, after this returns, the <code>Task_engine</code> returned by <a class="el" href="classflow_1_1async_1_1Task__qing__thread.html#aaf0191625ae2613a7351dc0515398903" title="Returns pointer to util::Task_engine such that post()ing to it will cause the subsequent asynchronous...">task_engine()</a> shall not have been destroyed by this method. In particular, <code>post()</code> on that <code>Task_engine</code> object will still work without undefined behavior/crashing. The <code>post()</code>ed function just won't actually run. (It may run on another thread but not this one, since by definition this thread has been joined.) </p>

<p class="definition">Definition at line <a class="el" href="task__qing__thread_8cpp_source.html#l00259">259</a> of file <a class="el" href="task__qing__thread_8cpp_source.html">task_qing_thread.cpp</a>.</p>

<p class="reference">References <a class="el" href="log_8hpp_source.html#l00197">FLOW_LOG_INFO</a>, <a class="el" href="log_8hpp_source.html#l00227">FLOW_LOG_TRACE</a>, <a class="el" href="task__qing__thread_8hpp_source.html#l00268">m_own_task_engine</a>, <a class="el" href="task__qing__thread_8hpp_source.html#l00265">m_task_engine</a>, and <a class="el" href="task__qing__thread_8hpp_source.html#l00271">m_worker_thread</a>.</p>

<p class="reference">Referenced by <a class="el" href="task__qing__thread_8cpp_source.html#l00248">~Task_qing_thread()</a>.</p>
<div class="dynheader">
Here is the caller graph for this function:</div>
<div class="dyncontent">
<div class="center"><iframe scrolling="no" frameborder="0" src="classflow_1_1async_1_1Task__qing__thread_a6515b9f5240cea26b78e27ea99964ade_icgraph.svg" width="379" height="47"><p><b>This browser is not able to show SVG: try Firefox, Chrome, Safari, or Opera instead.</b></p></iframe>
</div>
</div>

</div>
</div>
<a id="aaf0191625ae2613a7351dc0515398903" name="aaf0191625ae2613a7351dc0515398903"></a>
<h2 class="memtitle"><span class="permalink"><a href="#aaf0191625ae2613a7351dc0515398903">&#9670;&nbsp;</a></span>task_engine()</h2>

<div class="memitem">
<div class="memproto">
      <table class="memname">
        <tr>
          <td class="memname"><a class="el" href="namespaceflow_1_1async.html#a968806f54b14c697fd76b3339a2bdbbf">Task_engine_ptr</a> flow::async::Task_qing_thread::task_engine </td>
          <td>(</td>
          <td class="paramname"></td><td>)</td>
          <td></td>
        </tr>
      </table>
</div><div class="memdoc">

<p>Returns pointer to <a class="el" href="namespaceflow_1_1util.html#ac3e89a8a271b0ddc76ac2a0ce488dea4" title="Short-hand for boost.asio event service, the central class of boost.asio.">util::Task_engine</a> such that <code>post()</code>ing to it will cause the subsequent asynchronous execution of that task in a way explained in the <a class="el" href="classflow_1_1async_1_1Task__qing__thread.html#abb03d1b5f50a2b6148da27139a2391da" title="Constructs object, immediately spawning new (worker) thread, memorizing a ref-counted reference to th...">Task_qing_thread()</a> constructor doc header. </p>
<p >This is the same object passed to ctor.</p>
<p >Do note that the user's saving a copy of this pointer can extend the life of the returned <code>Task_engine</code> (which is NOT at all the same as extending the life of <a class="el" href="classflow_1_1async_1_1Task__qing__thread.html#a3f9a0071880455c00a993d36c6040ae5" title="Returns the util::Thread – a thin wrapper around the native OS thread handle – corresponding to the w...">raw_worker_thread()</a>; also NOT at all the same as making it possible to actually execute work which requires threads).</p>
<p >Could technically be <code>const</code>, but <code>const</code> usage is OK to be conservative. In spirit, at least, it's not <code>const</code>.</p>
<dl class="section return"><dt>Returns</dt><dd>See above. </dd></dl>

<p class="definition">Definition at line <a class="el" href="task__qing__thread_8cpp_source.html#l00304">304</a> of file <a class="el" href="task__qing__thread_8cpp_source.html">task_qing_thread.cpp</a>.</p>

<p class="reference">References <a class="el" href="task__qing__thread_8hpp_source.html#l00265">m_task_engine</a>.</p>

</div>
</div>
<h2 class="groupheader">Member Data Documentation</h2>
<a id="a0a80c87ce824a15fb84a73d99f5d61ac" name="a0a80c87ce824a15fb84a73d99f5d61ac"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a0a80c87ce824a15fb84a73d99f5d61ac">&#9670;&nbsp;</a></span>m_own_task_engine</h2>

<div class="memitem">
<div class="memproto">
<table class="mlabels">
  <tr>
  <td class="mlabels-left">
      <table class="memname">
        <tr>
          <td class="memname"><a class="el" href="classbool.html">bool</a> flow::async::Task_qing_thread::m_own_task_engine</td>
        </tr>
      </table>
  </td>
  <td class="mlabels-right">
<span class="mlabels"><span class="mlabel">private</span></span>  </td>
  </tr>
</table>
</div><div class="memdoc">

<p>See constructor. </p>

<p class="definition">Definition at line <a class="el" href="task__qing__thread_8hpp_source.html#l00268">268</a> of file <a class="el" href="task__qing__thread_8hpp_source.html">task_qing_thread.hpp</a>.</p>

<p class="reference">Referenced by <a class="el" href="task__qing__thread_8cpp_source.html#l00259">stop()</a>, and <a class="el" href="task__qing__thread_8cpp_source.html#l00037">Task_qing_thread()</a>.</p>

</div>
</div>
<a id="a1f4a96efdc1820ddbb4a4bf49c0d38e6" name="a1f4a96efdc1820ddbb4a4bf49c0d38e6"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a1f4a96efdc1820ddbb4a4bf49c0d38e6">&#9670;&nbsp;</a></span>m_task_engine</h2>

<div class="memitem">
<div class="memproto">
<table class="mlabels">
  <tr>
  <td class="mlabels-left">
      <table class="memname">
        <tr>
          <td class="memname"><a class="el" href="namespaceflow_1_1async.html#a968806f54b14c697fd76b3339a2bdbbf">Task_engine_ptr</a> flow::async::Task_qing_thread::m_task_engine</td>
        </tr>
      </table>
  </td>
  <td class="mlabels-right">
<span class="mlabels"><span class="mlabel">private</span></span>  </td>
  </tr>
</table>
</div><div class="memdoc">

<p>See <a class="el" href="classflow_1_1async_1_1Task__qing__thread.html#aaf0191625ae2613a7351dc0515398903" title="Returns pointer to util::Task_engine such that post()ing to it will cause the subsequent asynchronous...">task_engine()</a>. </p>

<p class="definition">Definition at line <a class="el" href="task__qing__thread_8hpp_source.html#l00265">265</a> of file <a class="el" href="task__qing__thread_8hpp_source.html">task_qing_thread.hpp</a>.</p>

<p class="reference">Referenced by <a class="el" href="task__qing__thread_8cpp_source.html#l00259">stop()</a>, <a class="el" href="task__qing__thread_8cpp_source.html#l00304">task_engine()</a>, and <a class="el" href="task__qing__thread_8cpp_source.html#l00037">Task_qing_thread()</a>.</p>

</div>
</div>
<a id="a75b218e1b5f137ead984588107ef02b0" name="a75b218e1b5f137ead984588107ef02b0"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a75b218e1b5f137ead984588107ef02b0">&#9670;&nbsp;</a></span>m_worker_thread</h2>

<div class="memitem">
<div class="memproto">
<table class="mlabels">
  <tr>
  <td class="mlabels-left">
      <table class="memname">
        <tr>
          <td class="memname">boost::movelib::unique_ptr&lt;<a class="el" href="namespaceflow_1_1util.html#af030c3119f060a9630afca31098a78a5">util::Thread</a>&gt; flow::async::Task_qing_thread::m_worker_thread</td>
        </tr>
      </table>
  </td>
  <td class="mlabels-right">
<span class="mlabels"><span class="mlabel">private</span></span>  </td>
  </tr>
</table>
</div><div class="memdoc">

<p>Thread created in constructor. Not-a-thread after <a class="el" href="classflow_1_1async_1_1Task__qing__thread.html#a6515b9f5240cea26b78e27ea99964ade" title="Blocks the calling thread until the constructor-started thread has finished; if the underlying Task_e...">stop()</a>; not not-a-thread before <a class="el" href="classflow_1_1async_1_1Task__qing__thread.html#a6515b9f5240cea26b78e27ea99964ade" title="Blocks the calling thread until the constructor-started thread has finished; if the underlying Task_e...">stop()</a>. </p>

<p class="definition">Definition at line <a class="el" href="task__qing__thread_8hpp_source.html#l00271">271</a> of file <a class="el" href="task__qing__thread_8hpp_source.html">task_qing_thread.hpp</a>.</p>

<p class="reference">Referenced by <a class="el" href="task__qing__thread_8cpp_source.html#l00309">raw_worker_thread()</a>, <a class="el" href="task__qing__thread_8cpp_source.html#l00259">stop()</a>, and <a class="el" href="task__qing__thread_8cpp_source.html#l00037">Task_qing_thread()</a>.</p>

</div>
</div>
<a id="a981c21354bafc012748707a301b89d3e" name="a981c21354bafc012748707a301b89d3e"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a981c21354bafc012748707a301b89d3e">&#9670;&nbsp;</a></span>S_BAD_EXIT</h2>

<div class="memitem">
<div class="memproto">
<table class="mlabels">
  <tr>
  <td class="mlabels-left">
      <table class="memname">
        <tr>
          <td class="memname">const int flow::async::Task_qing_thread::S_BAD_EXIT = 1</td>
        </tr>
      </table>
  </td>
  <td class="mlabels-right">
<span class="mlabels"><span class="mlabel">static</span></span>  </td>
  </tr>
</table>
</div><div class="memdoc">

<p><code>exit()</code> code returned to OS in the event <a class="el" href="classflow_1_1async_1_1Task__qing__thread.html" title="Internally used building block of various concrete Concurrent_task_loop subclasses that encapsulates ...">Task_qing_thread</a> chooses to <code>exit()</code> the entire program (as of this writing, this occurs on uncaught exception by a user task). </p>

<p class="definition">Definition at line <a class="el" href="task__qing__thread_8hpp_source.html#l00070">70</a> of file <a class="el" href="task__qing__thread_8hpp_source.html">task_qing_thread.hpp</a>.</p>

</div>
</div>
<hr/>The documentation for this class was generated from the following files:<ul>
<li>async/detail/<a class="el" href="task__qing__thread_8hpp_source.html">task_qing_thread.hpp</a></li>
<li>async/detail/<a class="el" href="task__qing__thread_8cpp_source.html">task_qing_thread.cpp</a></li>
</ul>
</div><!-- contents -->
<!-- start footer part -->
<hr class="footer"/><address class="footer"><small>
Generated on Fri Mar 28 2025 22:55:35 for Flow by&#160;<a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.4
</small></address>
</body>
</html>
